/*
 * C/C++ KLIB Project
 * 
 * Copyright (c) 2012 Ken Zhang (cpp.china@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 */


#include "klib.h"
#include <string.h>
#include <stdio.h>

#define CSV_ITEM_BUF_SIZE	128

int read_csv_item(const char *csvstring, char *buffer, size_t bufsiz, int *num_read)
{
	int in_quotation = 0, len = strlen(csvstring), ibuf = 0, pos = 0;
	int done = 0, endline = 0;

	*num_read = 0;

	if (bufsiz == 0 || len == 0) {
		return -1;
	}

	while (pos < len && !done) {
		if (ibuf + 1 >= bufsiz) {
			buffer[ibuf] = '\0';
			*num_read = pos;
			return -1;
		}

		if (in_quotation) {
			if (strncmp(csvstring + pos, "\"\"", 2) == 0) {
				buffer[ibuf++] = '"';
				pos++;
			}
			else if (csvstring[pos] == '"') {
				in_quotation = 0;
			}
			else {
				buffer[ibuf++] = csvstring[pos];
			}
		}
		else {
			switch (csvstring[pos]) {
				case '"':
					in_quotation = 1;
					break;
				case ',':
					buffer[ibuf] = '\0';
					done = 1;
					break;
				case '\r':
					if (len > 0 && csvstring[pos+1] == '\n') {
						pos++;
					}
					buffer[ibuf] = '\0';
					done = 1;
					endline = 1;
					break;
				case '\n':
					if (len > 0 && csvstring[pos+1] == '\r') {
						pos++;
					}
					buffer[ibuf] = '\0';
					done = 1;
					endline = 1;
					break;
				default:
					buffer[ibuf++] = csvstring[pos];
					break;
			}
		}
		pos++;
	}

	if (pos >= len) {
		buffer[ibuf] = '\0';
	}

	*num_read = pos;
	return endline;
}

void readcsv(const char *csvstring)
{
	int num_read, ret, pos = 0;
	char buffer[CSV_ITEM_BUF_SIZE];

	do {
		ret = read_csv_item(csvstring + pos, buffer, sizeof(buffer), &num_read);
		pos += num_read;
		switch (ret) {
		case 0:
			printf("[%s]\t", buffer);
			break;
		case 1:
			printf("[%s]\n", buffer);
			break;
		}
	} while (ret >= 0);
}
